# BigData course project
# Serial version of training algorithm for SOM
# Sparse vector implementation 
#

import sys
import util
from util import log
from numpy import log as logn
from numpy import *

class SparseVec:
    # we know how to build ourselves from a string with 
    # following syntax:
    # <index1> <value1> <index2> <value2> ... <indexN> <valueN>    
    #
    # where is at most the dimension for this vector.
    #
    # We were originally going to use a dictionary (hash) for the non zero
    # values, but given we needed the dense representation anyway for speedup,
    # we opted to keep only the numpy array representation.
    #
    def __init__(self, n, s):
        #toks = s.split()
        #self.arr = zeros(n)
        self.arr = s.split()
	self.arr = [float(_) for _ in self.arr]
        #for i in xrange(0,len(toks),2):
        #    try:
        #        self.arr[int(toks[i])] = float(toks[i+1])
        #    except:
        #        log("Failed to parse sparse vector spec %s at %i: %s\n", 
        #            s, i, sys.exc_info())
        #        raise
        self.d = float(0)

    # calculates distance efficiently using numpy array representation
    # and caches it for reuse in computations        
    def dist(self, v):
        self.d = sqrt(sum((self.arr - v)**2))
        return self.d

    # knows how to dump back into an string
    def dump(self):
        dump_tup = lambda t: "%6d %.6f" % t
        fst = lambda t: t[0]
        not_zero = lambda t: t[1] != 0
        tups = filter(not_zero, zip(xrange(len(self.arr)), self.arr))
        return " ".join(map(dump_tup, sorted(tups, key=fst)))
